//
//  UIViewExtension.swift
//  JH
//  
//  Created by TokenWang on 2018/10/25.
//  Copyright © 2018年 T. All rights reserved.
//

import UIKit

extension UIView {

    var x: CGFloat {
        get {
            return self.frame.origin.x
        }
        set {
            var frame = self.frame
            frame.origin.x = newValue
            self.frame = frame
        }
    }
    var y: CGFloat {
        get {
            return self.frame.origin.y
        }
        set {
            var frame = self.frame
            frame.origin.y = newValue
            self.frame = frame
        }
    }
    var width: CGFloat {
        get {
            return self.frame.size.width
        }
        set {
            var frame = self.frame
            frame.size.width = newValue
            self.frame = frame
        }
    }
    var height: CGFloat {
        get {
            return self.frame.size.height
        }
        set {
            var frame = self.frame
            frame.size.height = newValue
            self.frame = frame
        }
    }
    var bottom: CGFloat {
        get {
            return self.y + self.height
        }
        set {
            var frame = self.frame
            frame.origin.y = newValue - frame.size.height
            self.frame = frame
        }
    }
    var right: CGFloat {
        get {
            return self.x + self.width
        }
        set {
            var frame = self.frame
            frame.origin.x = newValue - frame.size.width
            self.frame = frame
        }
    }
    
    /**
     *  centerX, centerY
     */
    var centerX:CGFloat {
        get {
            return self.center.x;
        }
        
        set {
            self.center.x = newValue
        }
    }
    
    var centerY:CGFloat {
        get {
            return self.center.y;
        }
        
        set {
            self.center.y = newValue
        }
    }
    
    var innerCenter: CGPoint {
        return CGPoint(x: self.width/2, y: self.height/2)
    }
    
  
    func snapshot() -> UIImage {
        return self.snapshotWithCompression(1)
    }
    
    func snapshotWithCompression(_ compression: CGFloat) -> UIImage {
        let gSize = self.bounds.size
        UIGraphicsBeginImageContextWithOptions(gSize, false, 0.0)
        self.layer.render(in: UIGraphicsGetCurrentContext()!)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        let imgData = img!.jpegData(compressionQuality: compression)
        if compression < 1 {
            return UIImage(data: imgData!)!
        } else {
            return img!
        }
    }
    
    func foundCurrentViewController() -> AnyObject {
        guard self.superview != nil else {
            return self
        }
        var next = self.superview
        while (next != nil) {
            let responder = next?.next
            if let nextResponder = responder, nextResponder.isKind(of: UIViewController.self) {
                return nextResponder
            }
            next = next?.superview
        }
        return self
    }
    
    private struct AssociatedKeys {
        static var descriptiveName = "AssociatedKeys.DescriptiveName.blurView"
    }
    
    private (set) var blurView: BlurView {
        get {
            if let blurView = objc_getAssociatedObject(
                self,
                &AssociatedKeys.descriptiveName
                ) as? BlurView {
                return blurView
            }
            self.blurView = BlurView(to: self)
            return self.blurView
        }
        set(blurView) {
            objc_setAssociatedObject(
                self,
                &AssociatedKeys.descriptiveName,
                blurView,
                .OBJC_ASSOCIATION_RETAIN_NONATOMIC
            )
        }
    }
    
    class BlurView {
        
        private var superview: UIView
        private var blur: UIVisualEffectView?
        private var editing: Bool = false
        private (set) var blurContentView: UIView?
        private (set) var vibrancyContentView: UIView?
        
        var animationDuration: TimeInterval = 0.1
        
        /**
         * Blur style. After it is changed all subviews on
         * blurContentView & vibrancyContentView will be deleted.
         */
        var style: UIBlurEffect.Style = .light {
            didSet {
                guard oldValue != style,
                    !editing else { return }
                applyBlurEffect()
            }
        }
        /**
         * Alpha component of view. It can be changed freely.
         */
        var alpha: CGFloat = 0 {
            didSet {
                guard !editing else { return }
                if blur == nil {
                    applyBlurEffect()
                }
                let alpha = self.alpha
                UIView.animate(withDuration: animationDuration) {
                    self.blur?.alpha = alpha
                }
            }
        }
        
        init(to view: UIView) {
            self.superview = view
        }
        
        func setup(style: UIBlurEffect.Style, alpha: CGFloat) -> Self {
            self.editing = true
            
            self.style = style
            self.alpha = alpha
            
            self.editing = false
            
            return self
        }
        
        func enable(isHidden: Bool = false) {
            if blur == nil {
                applyBlurEffect()
            }
            
            self.blur?.isHidden = isHidden
        }
        
        private func applyBlurEffect() {
            blur?.removeFromSuperview()
            
            applyBlurEffect(
                style: style,
                blurAlpha: alpha
            )
        }
        
        private func applyBlurEffect(style: UIBlurEffect.Style,
                                     blurAlpha: CGFloat) {
            superview.backgroundColor = UIColor.clear
            
            let blurEffect = UIBlurEffect(style: style)
            let blurEffectView = UIVisualEffectView(effect: blurEffect)
            
            let vibrancyEffect = UIVibrancyEffect(blurEffect: blurEffect)
            let vibrancyView = UIVisualEffectView(effect: vibrancyEffect)
            blurEffectView.contentView.addSubview(vibrancyView)
            
            blurEffectView.alpha = blurAlpha
            
            superview.insertSubview(blurEffectView, at: 0)
            
            blurEffectView.addAlignedConstrains()
            vibrancyView.addAlignedConstrains()
            
            self.blur = blurEffectView
            self.blurContentView = blurEffectView.contentView
            self.vibrancyContentView = vibrancyView.contentView
        }
    }
    
    
    private func addAlignedConstrains() {
        translatesAutoresizingMaskIntoConstraints = false
        addAlignConstraintToSuperview(attribute: NSLayoutConstraint.Attribute.top)
        addAlignConstraintToSuperview(attribute: NSLayoutConstraint.Attribute.leading)
        addAlignConstraintToSuperview(attribute: NSLayoutConstraint.Attribute.trailing)
        addAlignConstraintToSuperview(attribute: NSLayoutConstraint.Attribute.bottom)
    }
    
    private func addAlignConstraintToSuperview(attribute: NSLayoutConstraint.Attribute) {
        superview?.addConstraint(
            NSLayoutConstraint(
                item: self,
                attribute: attribute,
                relatedBy: NSLayoutConstraint.Relation.equal,
                toItem: superview,
                attribute: attribute,
                multiplier: 1,
                constant: 0
            )
        )
    }
    
    func viewRotate() -> Void {
        
        let transformAnima = CABasicAnimation.init(keyPath: "transform.rotation.y")
        transformAnima.fromValue = [0]
        transformAnima.toValue = NSNumber.init(value: Double.pi)
    }
    
    func addShadow() -> Void {
        
        let shadowPath = UIBezierPath.init(rect: self.bounds)
        self.layer.masksToBounds = false
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOffset = CGSize.init(width: 1.0, height: 1.0)
        self.layer.shadowOpacity = 0.1
        self.layer.shadowPath = shadowPath.cgPath
    }
    
    func addShadowOnBottom() -> Void {
        
        let shadowPath = UIBezierPath.init(rect: self.bounds)
        self.layer.masksToBounds = false
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOffset = CGSize.init(width: 1.0, height: -1.0)
        self.layer.shadowOpacity = 0.1
        self.layer.shadowPath = shadowPath.cgPath
    }
    
    class func label(textcolor:UIColor,font:CGFloat,backgroundColor:UIColor,alignment:NSTextAlignment) -> UILabel {
        
        let label = UILabel()
        label.text = "lableText"
        label.textColor = textcolor
        label.textAlignment = alignment
        label.font = UIFont.systemFont(ofSize: font)
        label.backgroundColor = backgroundColor
        return label
    }
    
    class func button(textcolor:UIColor,font:CGFloat,backgroundColor:UIColor,cornerRadiu:CGFloat) -> UIButton {
    
        let button = UIButton()
        button.setTitle("btnText", for: .normal)
        button.setTitleColor(textcolor, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: font)
        button.backgroundColor = backgroundColor
        if cornerRadiu > 0 {
                button.backgroundColor = backgroundColor
                button.layer.cornerRadius = cornerRadiu
            }
        return button
    }
    
    class func imageView(name:String,backgroundColor:UIColor,cornerRadiu:CGFloat) -> UIImageView {
        
        let imageView = UIImageView()
        imageView.image = UIImage(named:name)
        imageView.backgroundColor = backgroundColor
        imageView.contentMode = .scaleAspectFit
        if cornerRadiu > 0 {
                imageView.layer.cornerRadius = cornerRadiu
                imageView.layer.masksToBounds = true
            }
        return imageView
    }
    
    class func view(backgroundColor:UIColor,cornerRadiu:CGFloat) -> UIView {
        
        let view = UIView()
        view.backgroundColor = backgroundColor
        if cornerRadiu > 0 {
                view.layer.cornerRadius = cornerRadiu
                view.layer.masksToBounds = true
            }
        return view
    }
    
    

}
